[IA64] bug fixes for recent ioports patch
authorawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 31 Jul 2006 19:10:39 +0000 (13:10 -0600)
committerawilliam@xenbuild.aw <awilliam@xenbuild.aw>
Mon, 31 Jul 2006 19:10:39 +0000 (13:10 -0600)
Bug fixes: dom0 do not virtualize IO space, do not over-deny IO ports.

Signed-off-by: Tristan Gingold <tristan.gingold@bull.net>
xen/arch/ia64/xen/mm.c
xen/include/asm-ia64/linux-xen/asm/io.h

index 5a24f06a8fac89b81e215a992ee05c3b930fcb61..f968d57e699c2114c9203bd2e93f350c345dfafe 100644 (file)
@@ -908,6 +908,10 @@ ioports_permit_access(struct domain *d, unsigned long fp, unsigned long lp)
     if (ret != 0)
         return ret;
 
+    /* Domain 0 doesn't virtualize IO ports space. */
+    if (d == dom0)
+        return 0;
+
     fp_offset = IO_SPACE_SPARSE_ENCODING(fp) & ~PAGE_MASK;
     lp_offset = PAGE_ALIGN(IO_SPACE_SPARSE_ENCODING(lp));
 
@@ -918,6 +922,16 @@ ioports_permit_access(struct domain *d, unsigned long fp, unsigned long lp)
     return 0;
 }
 
+static int
+ioports_has_allowed(struct domain *d, unsigned long fp, unsigned long lp)
+{
+    unsigned long i;
+    for (i = fp; i < lp; i++)
+        if (rangeset_contains_singleton(d->arch.ioport_caps, i))
+            return 1;
+    return 0;
+}
+
 int
 ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp)
 {
@@ -936,9 +950,18 @@ ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp)
 
     for (off = fp_offset; off <= lp_offset; off += PAGE_SIZE) {
         unsigned long mpaddr = IO_PORTS_PADDR + off;
+        unsigned long port;
         volatile pte_t *pte;
         pte_t old_pte;
 
+        port = IO_SPACE_SPARSE_DECODING (off);
+        if (port < fp || port + IO_SPACE_SPARSE_PORTS_PER_PAGE > lp) {
+            /* Maybe this covers an allowed port.  */
+            if (ioports_has_allowed(d, port,
+                                    port + IO_SPACE_SPARSE_PORTS_PER_PAGE))
+                continue;
+        }
+
         pte = lookup_noalloc_domain_pte_none(d, mpaddr);
         BUG_ON(pte == NULL);
         BUG_ON(pte_none(*pte));
index 9c798f869c8d73e3d2f11f1298abe287abefe593..3ad22c0547614b1b0197ca160c9f04503122d589 100644 (file)
 
 #define IO_SPACE_SPARSE_ENCODING(p)    ((((p) >> 2) << 12) | (p & 0xfff))
 
+#ifdef XEN
+/* Offset to IO port; do not catch error.  */
+#define IO_SPACE_SPARSE_DECODING(off)  ((((off) >> 12) << 2) | (off & 0x3))
+#define IO_SPACE_SPARSE_PORTS_PER_PAGE (0x4 << (PAGE_SHIFT - 12))
+#endif
+
 struct io_space {
        unsigned long mmio_base;        /* base in MMIO space */
        int sparse;